package com.scalar.chiptrack.operations.process;

import com.scalar.ScalarException;
import com.scalar.chiptrack.commons.UOM;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.chiptrack.db.DBXException;
import com.scalar.chiptrack.operations.process.dao.BomPartEntryDAO;
import com.scalar.chiptrack.operations.process.dao.WorkflowDBManager;
import com.scalar.chiptrack.operations.processtypesetup.dao.ProcessTypeSetupDAO;
import com.scalar.chiptrack.utils.ConfigManager;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
public class WorkFlowAction extends HttpServlet
{
	public void doGet(HttpServletRequest request,
					   HttpServletResponse response) 
			   throws ServletException, IOException
	{
		ServletContext app = getServletContext();
        ObjectInputStream inputFromApplet = null;
        ObjectOutputStream outputToApplet = null;
        try
		{
			String str = null;
			String productName = "";

			HashMap map = new HashMap();
			inputFromApplet = new ObjectInputStream(request.getInputStream());
			Object obj = inputFromApplet.readObject();
			//inputFromApplet.close();
            //inputFromApplet = null;
            String seprator = "#$#$#$";
			str = (String) obj;
			//System.out.println(" str in servlet "+ str);
            if( ( str.indexOf( seprator ) == -1) && str.equalsIgnoreCase( "vendors" ) )
			{
				outputToApplet 	= new ObjectOutputStream(response.getOutputStream());
				map 			= WorkflowDBManager.getAllVendorLocations();
				outputToApplet.writeObject( map );
			}
			else if(  ( str.indexOf( seprator ) == -1) && str.equalsIgnoreCase( "parameters" ) )
			{
				outputToApplet 	= new ObjectOutputStream(response.getOutputStream());
				map 			= WorkflowDBManager.getAllProcessParameters();
				outputToApplet.writeObject( map );
			}
            /*else if(str.startsWith("packageTypes") )
            {
                ArrayList packageTypeList = PurchaseOrderDAO.loadPackTypeList();
                Iterator iter = packageTypeList.iterator();
                Vector packageTypes = new Vector();
                while( iter.hasNext())
                {
                    String packageType =  (String) iter.next();
                    packageTypes.add( packageType );
                }
                outputToApplet = new ObjectOutputStream( response.getOutputStream() );
                outputToApplet.writeObject( packageTypes );
            }*/
            else if ( str.startsWith ( "comboMap" ) )
            {
                String processType  = str.substring( 8 );
                HashMap comboMap    = getComboMapForProcessType ( processType );
                map                 = WorkflowDBManager.getAllProcessParameters();
                HashMap parametersMap = ( HashMap) map.get ( processType );
                Vector parametersList = ( parametersMap == null ) ? null : ( Vector ) parametersMap.get ( "parameters");
                checkParameterValuesInComboMap ( parametersList, comboMap );
                outputToApplet = new ObjectOutputStream( response.getOutputStream() );
                outputToApplet.writeObject( comboMap );
            }
            else if ( str.equalsIgnoreCase( "saveActivityAttributes" ) )
            {
                Map attributes = (Map)inputFromApplet.readObject();
                WorkflowDBManager workFlowdb 	= new WorkflowDBManager();
                DBTransaction dbTransaction = null;
                boolean success = false;
                String msg = null;
                outputToApplet = new ObjectOutputStream( response.getOutputStream() );
                try
                {
                    dbTransaction = DBTransaction.getInstance();
                    dbTransaction.begin();
                    String baseProductID = WorkflowDBManager.getProductId( dbTransaction, (String)attributes.get ( "baseProductName" ) );
                    msg = workFlowdb.saveActivityInDB( dbTransaction, attributes, baseProductID );
                    dbTransaction.commit();
                    msg = "SUCCESS:" + msg;
                    success = true;
                }
                catch ( ScalarException e )
                {
                    e.printStackTrace();
                    msg = "ERROR: Could not save Process. Cause:" + e.getRootCause().getMessage();
                }
                finally
                {
                    if ( dbTransaction != null && !success )
                    {
                        try { dbTransaction.rollback(); } catch ( DBXException ignore ) {}
                    }
                }
                outputToApplet.writeObject( msg );
            }
            else if ( str.equalsIgnoreCase( "deleteProcess" ) )
            {
                Map params = (Map)inputFromApplet.readObject();
                WorkflowDBManager workFlowdb 	= new WorkflowDBManager();
                DBTransaction dbTransaction = null;
                boolean success = false;
                String msg = null;
                outputToApplet = new ObjectOutputStream( response.getOutputStream() );
                try
                {
                    dbTransaction = DBTransaction.getInstance();
                    dbTransaction.begin();
                    int processStepId = Integer.parseInt ( (String)params.get("processStepId") );
                    String xpdl = (String)params.get("xpdl");
                    String baseProductName = (String)params.get("baseProductName");
                    msg = workFlowdb.deleteProcess( dbTransaction, processStepId );
                    if ( "SUCCESS".equalsIgnoreCase( msg ) )
                    {
                        //todo need to save xpdl to disk
                        ByteArrayInputStream bais = new ByteArrayInputStream(xpdl.getBytes() );
                        String flag = WorkflowProcess.saveProcessToDB( bais , baseProductName , app.getRealPath( baseProductName+".xpdl" ), "File" );
                        if ( !"success".equalsIgnoreCase( flag ) )
                        {
                            Exception e = new ScalarException( "Could not save XPDL to disk" );
                            throw new ScalarException ( "Could not save xpdl to disk", e );
                        }
                    }
                    
                    dbTransaction.commit();
                    success = true;
                }
                catch ( ScalarException e )
                {
                    e.printStackTrace();
                    msg = e.getRootCause().getMessage();
                }
                finally
                {
                    if ( dbTransaction != null && !success )
                    {
                        try { dbTransaction.rollback(); } catch ( DBXException ignore ) {}
                    }
                }
                outputToApplet.writeObject( msg );
            }
            else if( str.indexOf( seprator ) > 0 )
			{
				int i = str.lastIndexOf( seprator );
				productName = str.substring( i + seprator.length() );
				str = str.substring(0,i);
				//System.out.println(str +" sssss "+ productName);
                if( str.equals("vendorsWithLosts") )
                {
					outputToApplet = new ObjectOutputStream( response.getOutputStream() );
                    ArrayList vendorsWithLots = WorkflowDBManager.getVendorsWithLots( productName );
				    outputToApplet.writeObject( vendorsWithLots );
                }
				else if( str.equals("getFile") )
				{
					outputToApplet = new ObjectOutputStream( response.getOutputStream() );
                    if (ConfigManager.getBooleanProperty(ConfigManager.SHOW_PRODUCT_SETUP_FROM_DB ) )
                    {
					    outputToApplet.writeObject( getDocumentFromDB( productName ) );
                    }
                    else
                    {
                        outputToApplet.writeObject( getDocument( productName ) );
                    }
				}
				else if(str.startsWith("PARTNUMBER"))
				{
					outputToApplet = new ObjectOutputStream( response.getOutputStream() );
					outputToApplet.writeObject( WorkflowProcess.getDupPartNumbers( productName ) );
				}
				else if(str.startsWith("MARKETINGPARTNUMBER"))
				{
					outputToApplet = new ObjectOutputStream( response.getOutputStream() );
					outputToApplet.writeObject( WorkflowProcess.getDupMktPartNumbers( productName ) );
				}
                else if(str.startsWith("BomParts") )
                {
                    String processStepId = productName;
                    ArrayList bomPartsList = BomPartEntryDAO.getBomPartsForAssembly( processStepId);
                    Iterator iter = bomPartsList.iterator();
                    Vector bomPartsVector = new Vector();
                    while( iter.hasNext())
                    {
                        BomPartForReport bomPart = (BomPartForReport) iter.next();
                        Vector bomPartVector = new Vector();
                        bomPartVector.add( bomPart.getBomPartNo());
                        bomPartVector.add( bomPart.getQtyReqPerUnit());
                        bomPartsVector.add( bomPartVector);
                    }
                    outputToApplet = new ObjectOutputStream( response.getOutputStream() );
                    outputToApplet.writeObject( bomPartsVector );
                }
                else if ( str.equals( "loadActivityAttributes" ) )
                {
                    outputToApplet = new ObjectOutputStream( response.getOutputStream() );
					outputToApplet.writeObject( WorkflowDBManager.getActivityAttributesMap( null, Integer.parseInt ( productName ) ) );
                }
                else
				{
					String flag = "";
					int x = str.lastIndexOf( seprator );
					String location = str.substring( x + seprator.length() );
					str = str.substring(0, x);
					System.out.println("Location "+ location);

					ByteArrayInputStream bais = new ByteArrayInputStream(str.getBytes() );

					flag = WorkflowProcess.saveProcessToDB( bais , productName , app.getRealPath( productName+".xpdl" ), location );

					outputToApplet = new ObjectOutputStream(response.getOutputStream());
					outputToApplet.writeObject( flag );
				}
			}

			outputToApplet.flush();
			outputToApplet.close();
            outputToApplet = null;
        }
		catch(Exception e)
		{
			e.printStackTrace();
		}
        finally
        {
            if ( inputFromApplet != null )
            {
                try { inputFromApplet.close(); } catch ( IOException ignore ) {}
            }
            if ( outputToApplet != null )
            {
                try { outputToApplet.close(); } catch ( IOException ignore ) {}
            }
        }
    }
	
    private File getDocument( String filename )
    {
		ServletContext app = getServletContext();
        //System.out.println( app.getRealPath( filename+".xpdl" ) );
    	File f = new File( app.getRealPath( filename+".xpdl" ));
		if(f.exists())
		{
			return f;
		}
		else
		{	
			WorkflowProcess.writeFile( filename, new ArrayList(), new ArrayList(), app.getRealPath( filename+".xpdl" ));
			f = new File( app.getRealPath(filename+".xpdl"));
		}
	    return f;
    }

    private Boolean getDocumentFromDB( String filename )
    {
		ServletContext app = getServletContext();
    	Boolean success = new Boolean( "FALSE" );
		try
		{
			WorkflowProcess.buildFileFromDB( filename, app.getRealPath( filename+".xpdl" ) );
			success = new Boolean( "TRUE" );
		}
		catch( Exception e )
		{
			e.printStackTrace();
		}

        return success;
    }

    public void doPost(HttpServletRequest req, HttpServletResponse res)
				throws ServletException, IOException
	{
		doGet(req,res);
	}

    private HashMap getComboMapForProcessType ( String processType )
    {
        HashMap comboMap = null;
        if ( processType == null || processType.trim().length() == 0 )
        {
            return null;
        }
        try
        {
            comboMap = ProcessTypeSetupDAO.getComboVectorMapForProcessType( null, processType );
        }
        catch( ScalarException e ) { }
        return comboMap;
    }
    /**
     * used to add the process parameter value to combo if not exists.
     * @param processParametersList
     * @param comboMap
     */
    private void checkParameterValuesInComboMap ( Vector processParametersList, HashMap comboMap )
    {
        if ( processParametersList == null || comboMap == null )
        {
            return;
        }
        int processParametersSize   = processParametersList.size();
        Vector processParameter     = null;
        Vector parameterValues      = null;
        ArrayList unitsOfmeasurement= null;
        int unitsOfmeasurementSize  = 0;
        try
        {
            unitsOfmeasurement = ProcessTypeSetupDAO.getUnitsOfMesurment();
            unitsOfmeasurementSize = (unitsOfmeasurement == null ) ? 0 : unitsOfmeasurement.size();
        }
        catch (ScalarException e)
        {
        }
        for ( int i=0; i < processParametersSize; i++ )
        {
            processParameter    = ( Vector ) processParametersList.get ( i );
            String paramName    = ( processParameter == null ) ? null : (String)processParameter.get ( 0 );
            String paramUnit    = ( processParameter == null ) ? null : (String)processParameter.get ( 1 );
            String paramVal     = ( processParameter == null ) ? null : (String)processParameter.get ( 2 );
            String baseUOM      = null;
            for ( int k = 0; k < unitsOfmeasurementSize; k++ )
            {
                UOM uom = ( UOM ) unitsOfmeasurement.get ( k );
                if ( paramUnit != null && paramUnit.equalsIgnoreCase( uom.getUom() ) )
                {
                    baseUOM = uom.getBaseUom();
                    break;
                }
            }
            parameterValues     =   ( Vector )comboMap.get ( paramName );
            if ( parameterValues != null && processParameter != null )
            {
                if ( paramVal != null && paramVal.trim().length() != 0 )
                {
                    int parameterValuesSize = parameterValues.size();
                    boolean matchFound  = false;
                    String parameterValue = null;
                    for ( int j = 0; j < parameterValuesSize; j++ )
                    {
                        parameterValue = ( String )parameterValues.get ( j );
                        if ( baseUOM != null )
                        {
                            if ( "DOUBLE".equalsIgnoreCase( baseUOM ) )
                            {
                                double tempParamVal         = 0;
                                double tempParameterValue   = 0;
                                try
                                {
                                    tempParamVal = Double.parseDouble ( paramVal.trim() );
                                    tempParameterValue = Double.parseDouble ( parameterValue.trim() );
                                    if ( tempParamVal == tempParameterValue )
                                    {
                                        matchFound = true;
                                        break;
                                    }
                                }catch ( Exception e ) { }
                            }
                            else if ( "INT".equalsIgnoreCase( baseUOM ) )
                            {
                                int tempParamVal         = 0;
                                int tempParameterValue   = 0;
                                try
                                {
                                    tempParamVal = Integer.parseInt ( paramVal.trim() );
                                    tempParameterValue = Integer.parseInt ( parameterValue.trim() );
                                    if ( tempParamVal == tempParameterValue )
                                    {
                                        matchFound = true;
                                        break;
                                    }
                                }catch ( Exception e ) { }
                            }
                            else if ( paramVal.equals( parameterValue ) )
                            {
                                matchFound  = true;
                                break;
                            }
                        }
                        else if ( paramVal.equals( parameterValue ) )
                        {
                            matchFound  = true;
                            break;
                        }
                    }
                    if ( !matchFound )
                    {
                        parameterValues.add ( paramVal );
                    }
                }
            }
        }
    }
}